;+
; NAME:
;       WRITE_BGPS_CSV
;
; PURPOSE:
;       Write out the BGPS structure back into a BGPS Distance
;       Database CSV file after modification by other routines. 
;
; CATEGORY:
;       BGPS distance-omnibus Utility
;
; CALLING SEQUENCE:
;       write_bgps_csv, filename, bgps_struct, csv_struct [,/VERBOSE]
;
; INPUTS:
;       filename    -- Filename of the to-be-written BGPS Distance
;                      Database CSV file
;       bgps_struct -- Array of BGPS structures containing the
;                      information read in with READ_BGPS_CSV (and
;                      modified by other routines)
;       csv_struct  -- Structure returned by READ_BGPS_CSV containing
;                      information about the CSV file (possibly
;                      modified by other routines)
;
; OPTIONAL INPUTS:
;       NULL  -- String to include in the CSV file for null cells
;                (default: 'null')
;
; KEYWORD PARAMETERS:
;       VERBOSE -- Print out information about the output CSV file
;
; OUTPUTS:
;       Writes out a CSV file with the 3 header lines read in from the
;       original CSV file
;
; OPTIONAL OUTPUTS:
;       NONE
;
; EXAMPLE:
;       write_bgps_csv,'bgps_distance_database.csv', struct_arr, csv_struct
;
; NOTES:
;       This routine is a modified version of the routine
;       WRITE_CSV.pro introduced in IDL v7.1
;
; MODIFICATION HISTORY:
;       Created:  06/01/10, TPEB -- Initial version is heavily modified
;                                   version of WRITE_CSV.pro (IDL 7.1)
;       Modified: 06/03/10, TPEB -- Modified write code to reflect
;                                   change in READ_ routine to an
;                                   array of structures.
;-

PRO WRITE_BGPS_CSV, filename, instruct, csv_struct, $
                    NULL=nullstr, VERBOSE=verbose
  
  IF KEYWORD_SET( verbose ) THEN verbose=1b ELSE verbose=0b
  
  ;; Set the 'null' replacement
  IF n_elements(nullstr) EQ 0 THEN nullstr='null'
  
  ;; Read in array of header names
  header_names = TAG_NAMES( instruct[0] )
  
  ;; Check to see if columns have been added to the CSV file outside
  ;; of officially sanctioned ADD_COLUMN_BGPS_CSV.pro
  IF (n_elements(header_names) NE csv_struct.ncols ) THEN BEGIN
     IF verbose THEN $
        message,'One or more columns have been added to CSV file outside of ADD_COLUMN_BGPS_CSV...',/inf
     message,$
        string(n_elements(header_names),csv_struct.ncols,format=$
               "('New Struct has ',I0,' columns, original CSV had ',I0)")
     
  ENDIF
    
  ;; Open output file for writitng
  openw, lun, filename, /GET_LUN
  
  ;; Write header rows to file
  ;; Column Names
  FOR i=0L, csv_struct.ncols-2 DO $
     printf,lun,csv_struct.col_name[i],format='(A,",",$)'
  printf,lun,csv_struct.col_name[csv_struct.ncols-1]
  ;; Column Data Types
  FOR i=0L, csv_struct.ncols-2 DO $
     printf,lun,strlowcase(csv_struct.col_type[i]),format='(A,",",$)'
  printf,lun,strlowcase(csv_struct.col_type[csv_struct.ncols-1])
  ;; Column units
  FOR i=0L, csv_struct.ncols-2 DO $
     printf,lun,csv_struct.col_units[i],format='(A,",",$)'
  printf,lun,csv_struct.col_units[csv_struct.ncols-1]
  
  
  ;; Start writing data to file  (if (double) = 0.d, then print 'null')
  FOR i=0L, csv_struct.nrows-1 DO BEGIN
     strline = ''
     FOR j=0L, csv_struct.ncols-1 DO BEGIN
        CASE size(instruct[i].(j), /TYPE) OF
           7 : strline += string(instruct[i].(j), FORMAT='(%"%s",$)')
           3 : strline += string(instruct[i].(j), FORMAT='(I0,$)')
           5 : IF (instruct[i].(j) EQ 0.d) THEN $
              strline += string(nullstr, FORMAT='(%"%s",$)') ELSE $
                 strline += string(instruct[i].(j), FORMAT='(G0.10,$)')
        ENDCASE
        IF j NE csv_struct.ncols-1 THEN strline += string(',', FORMAT='(A1,$)')
     ENDFOR
     printf, lun, strline
  ENDFOR

  IF verbose THEN $
     message,$
     string(csv_struct.ncols,csv_struct.nrows,format=$
            "('Wrote CSV file with ',I0,' columns and ',I0,' rows')"),/inf
  
  ;; Clean Up
  close, lun
  free_lun, lun
    
END
